<template>
  <!-- 登录、注册切换 -->
  <div class="index">
    <div class="login" style="box-shadow: var(--el-box-shadow);">
      <ul class="menu-tab">
        <li :class="{ 'current': current_menu === item.type}" @click="handlerToggleMenu(item.type)"
            v-for="item in data.tab_menu" :key="item.type">
          {{ item.label }}
        </li>
      </ul>

      <!-- 登录、注册表单 -->
      <el-form :model="data.form" ref="loginFormRef" :rules="rules" label-width="120px" label-position="right" class="form" >
        <el-form-item label="用户名" prop="username">
          <el-input placeholder="请输入用户名" v-model="username" clearable />
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input type="password" placeholder="请输入密码" v-model="password" show-password/>
        </el-form-item>
        <el-form-item v-if="'register' === current_menu" label="确认密码" prop="password2">
          <el-input type="password" placeholder="请再次输入密码" v-model="password2" show-password/>
        </el-form-item>
        <el-form-item label="验证码" prop="code">
          <el-row :gutter="10" style="width: 100%;">
            <el-col :span="8">
              <el-input placeholder="请输入" v-model="code" title="区分大小写"/>
            </el-col>
            <el-col :span="8">
              <el-button type="primary" @click="handlerGetCode" :disabled="data.code_button_disabled" :loading="data.code_button_loading">
                  {{ data.code_button_text }}
              </el-button>
            </el-col>
            <el-col :span="8">
              <el-image v-if="data.form.code_url" :src="data.form.code_url" ></el-image>
            </el-col>
          </el-row>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handlerSubmit" style="width: 100%;" :disabled="data.submit_button_disabled">
            {{ current_menu === 'login' ? '登录' : '注册' }}
          </el-button>
        </el-form-item>
      </el-form>

    </div>
  </div>
  
</template>

<script lang="ts" setup>
  import { reactive, ref, toRefs } from 'vue';
  import { validate_password, validate_code4 } from '@/utils/validate';
  import type { FormInstance, FormRules } from 'element-plus';
  import sha1 from 'js-sha1';
  import { useRouter, useRoute } from 'vue-router';
  import cookies from '@/utils/cookies.js';
  import { usernameCount, userRegister, userLogin } from '@a/account';
  import { getCode } from '@a/code';

  const router = useRouter()
  const loginFormRef = ref(null);

  // 检查用户名是否存在
  const validateUsername = (rule, value, callback) =>{
      if (value == ''){
        callback(new Error('请输入用户名'));
      }else if (current_menu.value == 'register') {
        usernameCount(value)
        .then(response => {
          if (response.data.count > 0){
            callback(new Error('用户名已存在'));
          }else {
            callback();
          }
        })
        .catch(error => {
          console.log(error);
        })
      }else {
        callback();
      }
    }
  
    const validatePass = (rule, value, callback) => {
      let validate = validate_password(value);
      if (value == '') {
        callback(new Error('密码不能为空'));
      }else if (!validate) {
        callback(new Error('密码在6到20位之间,必须包含数字、字母'));
      }else {
        callback();
      }
    }
  
    const validatePass2 = (rule, value, callback) => {
      let validate = validate_password(value);
      if (value == ''){
        callback(new Error('确认密码不能为空'));
      }else if (!validate){
        callback(new Error('确认密码在6到20位之间,必须包含数字、字母'));
      }else if (value != data.form.password){
        callback(new Error('确认密码不一致'));
      }else {
        callback();
      }
    }

    const validateCode = (rule, value, callback) => {
      let validate = validate_code4(value);
      if (value == ''){
        callback(new Error('验证码不能为空'));
      }else if (!validate) {
        callback(new Error('请输入4位验证码'));
      }else {
        callback();
      }
    }

  const data = reactive({
    form: {
      username: '',
      password: '',
      password2: '',
      code: '',
      code_url: ''
    },
    tab_menu: [
      {'type': 'login', 'label': '登录' },
      { 'type': 'register', 'label': '注册' },
    ],
    code_button_disabled: false,
    code_button_loading: false,
    code_button_text: '获取',
    code_button_timer: null,
    submit_button_disabled: false
  })

  const ruleForm = reactive({
    username: '',
    password: '',
    password2: '',
    code: '',
    code_url: ''
  })
  
  const rules = reactive<FormRules<typeof ruleForm>>({
    username: [{ validator: validateUsername, trigger: 'blur'}],
    password: [{ validator: validatePass, trigger: 'blur'}],
    password2: [{ validator: validatePass2, trigger: 'blur'}],
    code: [{ validator: validateCode, trigger: 'blur'}],
  })

  let current_menu = ref(data.tab_menu[0].type);

  const handlerToggleMenu = (type) => {
    current_menu.value = type;
    resertForm();
  }


  // 获取验证码
  function handlerGetCode() {
    const name = data.form.username;
    if (!name) {
      ElMessage.error('请输入用户名');
      return;
    } else {
      data.code_button_loading = true;
      data.code_button_text = '获取中';
      getCode(name)
      .then(response => {
          if (response.code == 200){
            data.form.code_url = response.data.url;
            countdown();
          } else {
            ElMessage.warning(response.msg);
            data.code_button_loading = false;
            data.code_button_text = '获取';
          }
      })
      .catch(error => {
        ElMessage.error(error.response.data.msg || error.response.statusText);
        data.code_button_loading = false;
        data.code_button_text = '获取';
      })
    }
  }

  const handlerSubmit = () => {
    // 表单全校验
    loginFormRef.value.validate((valid) => {
      if(valid) {
        current_menu.value == 'login' ? login() : register();
      } else {
        return false;
      }
    })
  }

  /** 用户注册 */
  const register = () => {
    data.submit_button_disabled = true;
    const params = {
      username: data.form.username,
      password: sha1(data.form.password),
      code: data.form.code
    }
    userRegister(params)
    .then(response => {
        ElMessage.success('注册成功');
        resertForm();
        current_menu.value = 'login';
    })
    .catch(error => {
      ElMessage.error(error.response.data.msg || error.response.statusText)
      data.submit_button_disabled = false;
    })
  }

  /** 用户登录 */
  const login = () => {
    data.submit_button_disabled = true;
    const params = {
      username: data.form.username,
      password: sha1(data.form.password),
      code: data.form.code
    }
    userLogin(params)
    .then(response => {
      cookies.setCookie('token', response.data.Token);
      cookies.setCookie('id', response.data.id);
      cookies.setCookie('username', response.data.username);
      cookies.setCookie('refresh', response.data.refresh || '');
      router.push({ path: "/index"});
    })
    .catch(error => {
      console.log(error)
      ElMessage.error(error.response.data.msg == "其他未知错误" ? "用户名密码错误!" : error.response.data.msg);
      data.submit_button_disabled = false;
    })
  }

  const countdown = (time) => {
    let second = time || 60;
    data.code_button_disabled = true;
    data.code_button_loading = false;
    data.code_button_text = `倒计时${second}秒`;
    if(data.code_button_timer) { clearInterval(data.code_button_timer); }
    data.code_button_timer = setInterval(() => {
      second--;
      data.code_button_text = `倒计时${second}秒`;
      if(second <= 0) {
        data.code_button_text = '重新获取';
        data.code_button_disabled = false;
        data.submit_button_disabled = false;
        clearInterval(data.code_button_timer);
      }
    }, 1000)
  }

  const resertForm = () => {
    loginFormRef.value.resetFields();
    data.form.code_url = '';
    data.code_button_disabled = false;
    data.code_button_loading = false;
    data.code_button_text = '获取';
    // 判断是否存在定时器，有则删除
    data.code_button_timer && clearInterval(data.code_button_timer);
    data.submit_button_disabled = false;
  }

  
  const { username, password, password2, code, code_url } = toRefs(data.form)
</script>

<style scoped>
  .index {
    width: 100%;
    height: 100%;
    background: linear-gradient(to right, #1e8dfc, #05c915);
    display: flex;  
    justify-content: center;  
    align-items: center;
  }

  .login {
    width: 420px;
    background-color: white;
    padding: 30px 50px 30px 30px;
    border-radius: 10px;
    /* margin-right: 200px; */
  }

  .menu-tab {
    text-align: center;
  }
  
  .menu-tab li {
    display: inline-block;
    padding: 10px 24px;
    margin: 0 10px;
    /* background-color: rgb(227, 224, 224); */
    font-size: 14px;
    border-radius: 5px;
    cursor: pointer;
  }

  .current { background-color: rgba(0, 0, 0, .1);}

  .form {
    margin-top: 20px;
  }
</style>